﻿package net.wangit.jdbc.connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;

import net.wangit.framework.exception.ConfigurationException;
import net.wangit.jdbc.JDBCException;
import net.wangit.jdbc.transaction.JDBCTransaction;
import net.wangit.jdbc.transaction.TransactionImplementor;
import net.wangit.util.Checker;
import net.wangit.util.XMLUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Element;


public class ProxoolConnectionProvider implements ConnectionProvider {
	private static final Log log = LogFactory
			.getLog(ProxoolConnectionProvider.class);
	private String alias;
	private TransactionImplementor transaction;
	private int isolation;
	private static final HashMap<Integer, String> ISOLATION_LEVELS;

	@Override
	public void configure(String path, Element connectionNode)
			throws ConnectionException, JDBCException {
		transaction = new JDBCTransaction();
		alias = XMLUtil.getTextString(connectionNode, "alias", null);
		if (Checker.isEmpty(alias)) {
			log.error("alias is null!");
			throw new ConfigurationException(path, "alias is null!");
		} else {
			alias = "proxool." + alias;
		}
		try {
			isolation = XMLUtil.getTextInt(connectionNode, "isolation", -1);
		} catch (Exception e) {
			throw new ConfigurationException(path, "isolation is null!");
		}
	}

	@Override
	public TransactionImplementor getTransaction() {
		return transaction;
	}

	@Override
	public Connection getConnection() throws SQLException {
		Connection conn = DriverManager.getConnection(alias);
		if (isolation > 0)
			conn.setTransactionIsolation(isolation);
		if (!conn.getAutoCommit())
			conn.setAutoCommit(true);
		if (log.isDebugEnabled())
			log.debug((new StringBuilder("created connection to: "))
					.append(alias)
					.append(", Isolation Level: ")
					.append(isolationLevelToString(conn
							.getTransactionIsolation())).toString());
		return conn;
	}

	@Override
	public void closeConnection(Connection connection) throws SQLException {
		connection.close();
	}

	private String isolationLevelToString(int isolation) {
		return (new StringBuilder(String.valueOf(isolation))).append("(")
				.append(ISOLATION_LEVELS.get(new Integer(isolation)))
				.append(")").toString();
	}

	static {
		ISOLATION_LEVELS = new HashMap<Integer, String>();
		ISOLATION_LEVELS.put(new Integer(0), "NONE");
		ISOLATION_LEVELS.put(new Integer(1), "READ_UNCOMMITTED");
		ISOLATION_LEVELS.put(new Integer(2), "READ_COMMITTED");
		ISOLATION_LEVELS.put(new Integer(4), "REPEATABLE_READ");
		ISOLATION_LEVELS.put(new Integer(8), "SERIALIZABLE");
	}
}
